package person.learn.service.base;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.Repository;
import person.learn.util.DynamicSpecifications;
import person.learn.util.SearchFilter;

import java.lang.reflect.ParameterizedType;
import java.util.Map;

/**
 * Created by barton on 16-1-30.
 * 1.search()方法支持条件检索，但是只能支持字符串，number等常见类型的字段。如果想支持其他类型，比如Enum，Date
 * 类型的参数，请重写DynamicSpecifications类的bySearchFilter()方法。(例：EQ条件下，判断传递进来的值的类型是否是java.util.Date
 * (if javaType.getTypeName().equals("java.util.Date")),如果是，则将值转换成java.util.Date类型后，赋给filter.value)
 * 2.详细使用方法请看GoodsControllerTest。
 */
public abstract class BaseService<T> {
    private Class<T> entityClass;

    public BaseService() {
        entityClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 搜索信息
     *
     * @param searchParams 格式为OPERATOR_FIELDNAME
     * @param pageRequest  分页排序请求参数 size,page,sort
     * @return
     */
    public Page<T> search(Map<String, Object> searchParams, Pageable pageRequest) {
        Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
        Specification<T> spec = DynamicSpecifications.bySearchFilter(
                filters.values(), entityClass);
        if (!(getRepository() instanceof JpaSpecificationExecutor)) {
            throw new RuntimeException("Repository bean must be instances of" +
                    "JpaSpecificationExecutor.");
        }
        Page<T> mobiles = ((JpaSpecificationExecutor) getRepository()).findAll(
                spec, pageRequest);
        return mobiles;
    }

    public abstract Repository getRepository();
}
